package com.mspbots.attendance.trigger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mspbots.api.client.CoreClient;
import com.mspbots.attendance.controller.TenantAttendanceController;
import com.mspbots.attendance.model.TenantAttendance;
import com.mspbots.attendance.model.TriggerEventDTO;
import com.mspbots.attendance.request.TenantDTO;
import com.mspbots.attendance.service.TenantAttendanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

import static com.mspbots.common.TriggerEvent.ATTENDANCE_AUTO;

/**
 * @author Dinnes Zhang
 * @date
 */
@Slf4j
@Component
public class AutoOutTriggerEvent {
    private static final String REDIS_KEY_PREFIX_TENANT = "MSPBOTS:CONFIG:TENANT:";
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitMessagingTemplate messagingTemplate;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private CoreClient coreClient;
    @Autowired
    private TenantAttendanceService service;

    //    @Scheduled(initialDelay = 10000, fixedRate = 60 * 60 * 1000)
    public void produce() {
        log.debug("attendance schedule...");
        List tenants = redisTemplate.opsForList().range(REDIS_KEY_PREFIX_TENANT + "tenants", 0, -1);
        log.debug("tenants ...  {}", tenants);
        List<TenantDTO> tenantDTOS = objectMapper.convertValue(tenants, new TypeReference<List<TenantDTO>>() {
        });
        log.debug("tenantDTOS ...  {}", tenantDTOS);
        tenantDTOS.stream().filter(item -> item.getStatusId() == 1).forEach(tenantDTO ->
                service.findLastIn(tenantDTO.getId()).parallelStream().forEach(userIn -> {
                    if (LocalDateTime.now().isAfter(userIn.getLogTime().plusHours(15))) {
                        TenantAttendanceController.TenantAttendanceParams attendanceParams = new TenantAttendanceController.TenantAttendanceParams();
                        attendanceParams.setTenantId(tenantDTO.getId());
                        attendanceParams.setUserId(userIn.getUserId());
                        attendanceParams.setAction("out");
                        attendanceParams.setCreateTimeStart(userIn.getLogTime());
                        attendanceParams.setCreateTimeEnd(LocalDateTime.now());
                        TenantAttendance attendance = service.findAction(attendanceParams);
                        if (StringUtils.isEmpty(attendance)) {
                            TenantAttendance auto = new TenantAttendance();
                            auto.setTenantId(userIn.getTenantId());
                            auto.setUserId(userIn.getUserId());
                            auto.setTeamsUserId(userIn.getTeamsUserId());
                            auto.setFromType("mspbots-auto");
                            auto.setAction("out");
                            service.log(auto);
                            if (!StringUtils.isEmpty(userIn.getTeamsUserId()) || !StringUtils.isEmpty(userIn.getTenantUserId())) {
                                try {
                                    JsonNode payload = this.objectMapper.readTree(this.objectMapper.writeValueAsString(userIn));
                                    if (payload != null) {
                                        TriggerEventDTO triggerEventDTO = new TriggerEventDTO();
                                        triggerEventDTO.setTenantId(userIn.getTenantId());
                                        triggerEventDTO.setEventName(ATTENDANCE_AUTO.getEvent());
                                        triggerEventDTO.setScope(ATTENDANCE_AUTO.getScope());
                                        triggerEventDTO.setPayload(payload);
                                        triggerEventDTO.setUserInfo(payload);
                                        this.messagingTemplate.convertAndSend("msp.trigger.event", "", triggerEventDTO);
                                        log.info("cw msp.trigger.event Attendance Schedule:[{}] ", this.objectMapper.convertValue(triggerEventDTO, JsonNode.class));
                                    }
                                } catch (JsonProcessingException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                })
        );
    }
}
